/*
 * Copyright 2008 Federal Emergency Management Agency
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0 
 *    
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 *  
 */
package gov.fema.hazus.bdc.client.settings;

import gov.fema.hazus.bdc.client.common.ui.InCASTTabPanel;
import gov.fema.hazus.bdc.client.common.ui.Message;
import gov.fema.hazus.bdc.client.login.Login;
import gov.fema.hazus.bdc.shared.entity.User;

import java.util.Date;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.WindowResizeListener;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FormHandler;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.FormSubmitCompleteEvent;
import com.google.gwt.user.client.ui.FormSubmitEvent;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.SourcesTabEvents;
import com.google.gwt.user.client.ui.TabListener;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class Settings extends Composite {

    private static final String COOKIE_NAME_LANGUAGE = "___InCastLanguage___";
    private static final Date DATE_IN_THE_FUTURE = new Date(61854274800000L);
    
    private static Settings singleton = null;
    public static Settings get()
    {
        if( singleton == null )
        {
            singleton = new Settings();
        }
        return singleton;
    }
    
    // widgets
    private Cookies cookies;
    private VerticalPanel main = new VerticalPanel();
    private HorizontalPanel top = new HorizontalPanel();
    private HorizontalPanel bottom = new HorizontalPanel();
    private InCASTTabPanel tab = new InCASTTabPanel();
    private GeneralSettings generalSettings = new GeneralSettings();
    private ImportSettings importSettings = new ImportSettings();
    private UserSettings userSettings = new UserSettings();
    
    private RedRoverImportSettings redRoverImportSettings = new RedRoverImportSettings();
    private SettingsConstants constants;
    
    private UserList userList = UserList.get();
    
    private User user = null;
    
    public Settings()
    {
        singleton = this;
        

        
        constants = (SettingsConstants)GWT.create(SettingsConstants.class);
        
        main.setStyleName("settings-main");
        
        // set up the title
        Label title = new Label( constants.topnavSettings() );
        title.setStyleName("settings-title");
        
        // add title to top
        top.setStyleName("settings-button-bar");
        top.setHeight("40");
        top.add(title);
        main.add(top);
        
        // set up the tab panel
        tab.setStyleName("settings-tabbar");
        tab.setWidth("100%");
        tab.setHeight("100%");
        tab.add(generalSettings, constants.settingsGeneral());
        tab.add(userSettings, "Users");
        //tab.add(redRoverImportSettings, constants.settingsROVER());
        tab.selectTab(0);
        main.add(tab);
        
        main.setCellWidth(tab, "100%");
        main.setCellHeight(tab, "100%");
        
        // save bottom bar
        bottom.setStyleName("settings-north-button-bar");
        bottom.setHeight("40");
        Button save = new Button(constants.saveButton());
        
        // TODO: save settings in datastore
        // bottom.add(save);
        
        main.add(bottom);
        main.setCellWidth(bottom, "100%");
        
        
        tab.addTabListener(new TabListener() {
			
			public void onTabSelected(SourcesTabEvents arg0, int arg1) {
				
			}
			
			public boolean onBeforeTabSelected(SourcesTabEvents arg0, int arg1) {
				if(arg1 == 1)
				{
					showUserList();
				}
				return true;
			}
		});
        initWidget(main);
        
    }
    
    private class UserSettings extends Composite {

    	// vpanel
    	private VerticalPanel vpanel = new VerticalPanel();
    	
    	// get the user list
    	UserList userList = UserList.get();
    	UserEditor userEditor = UserEditor.get();
    	
    	
        public UserSettings()
        {
            constants = (SettingsConstants)GWT.create(SettingsConstants.class);
            
            vpanel.add(userList);
            vpanel.add(userEditor);
            
            UserEditor.get().setVisible(false);
            
            vpanel.setCellHeight(userList, "100%");
            vpanel.setCellWidth(userList, "100%");
            
            initWidget(vpanel);
            
        }


		public void showUserEditor() {
			
			userList.setVisible(false);
			vpanel.setCellHeight(userList, "0px");
			
			userEditor.setVisible(true);
			vpanel.setCellHeight(userEditor, "100%");
		}


		public void showUserList() {
			
			userEditor.setVisible(false);
			vpanel.setCellHeight(userEditor, "0px");
			
			userList.setVisible(true);
			vpanel.setCellHeight(userList, "100%");
			
			
			userList.getUsers();
			
			
		}

		public void addNewUser() {
			userEditor.addNewUser();
			showUserEditor();
		}    
       
    }
    
    private class GeneralSettings extends Composite {

    	// vpanel
    	private VerticalPanel vpanel = new VerticalPanel();
    	
    	// general
    	private FlexTable generalTable = new FlexTable();
        private ListBox languageListBox;
        
        // import
        private FormPanel csvForm = new FormPanel();
    	private FlexTable importTable = new FlexTable();
        
        public GeneralSettings()
        {
            
            constants = (SettingsConstants)GWT.create(SettingsConstants.class);
            
            Label language = new Label( constants.settingsLanguage() );
            languageListBox = new ListBox();
            languageListBox.addItem( constants.settingsEnglish(), "en");
            
            // TODO: We are holding off on other languages for now
            //languageListBox.addItem( constants.settingsSpanish(), "es");
            
            /*
             * Check the cookies to see what language we are in
             */
            String currentLanguage = cookies.getCookie(COOKIE_NAME_LANGUAGE);
            if( currentLanguage != null )
            {
                for (int i = 0; i < languageListBox.getItemCount(); i++)
                {
                        String value = languageListBox.getValue(i);
                        if(currentLanguage.equals(value))
                        {
                            languageListBox.setSelectedIndex(i);
                        }
                }
            }
            else
            {
                languageListBox.setSelectedIndex(0); // default language is en
            }
            
            languageListBox.addChangeListener(new ChangeLanguageListener());
            
            generalTable.setStyleName("general-settings-table");
            
            generalTable.setWidget(0, 0, language);
            generalTable.setWidget(0, 1, languageListBox);
            
            vpanel.add(generalTable);
            //vpanel.add(importSettings);
            
            initWidget(vpanel);
            
            
        }
        
        public class ChangeLanguageListener implements ChangeListener
        {
            public void onChange(Widget sender) {

                // cast the sender
                languageListBox = (ListBox) sender;
                
                // get the selected item
                String newLocale = languageListBox.getValue(languageListBox.getSelectedIndex());
                
                // change locale
                changeLocale(newLocale);
                
                // update the cookie
                setCookie(newLocale);
                
            }
            
        }      
        
        private native void changeLocale(String newLocale)/*-{
            // Uncomment the "debugger;" line to see how to set debug statements in JSNI code
            // When in web mode, if your browser has a JavaScript debugger attached, it will
            // launch at this point in the code (when the user changes locale through the menu system).
    
            //debugger;
    
            // Get the current location
            var currLocation = $wnd.location.toString();
            // Get rid of any GWT History tokens that might be present
            var noHistoryCurrLocArray = currLocation.split("#");
            var noHistoryCurrLoc = noHistoryCurrLocArray[0];
            // Get rid of any locale string
            var locArray = noHistoryCurrLoc.split("?");
            // Build the new href location and then send the browser there.
            $wnd.location.href = locArray[0]+"?locale="+newLocale;
            }-*/;
        
        private void setCookie(String locale)
        {
            cookies.setCookie(COOKIE_NAME_LANGUAGE, locale, DATE_IN_THE_FUTURE);
        }        
    }
    
   private class RedRoverImportSettings extends Composite {
        
        
        private FlexTable roverTable = new FlexTable();
        private FormPanel redRoverForm = new FormPanel();
        
        public RedRoverImportSettings()
        {
         
            // provide link to RedRover setup.exe
            HTML link = new HTML("<a href=\"downloads/redrover-setup.exe\">redrover-setup.exe</a>");
            Label linkLabel = new Label( constants.settingsRedRoverLinkText() );
            roverTable.setWidget(0, 0, linkLabel);
            roverTable.setWidget(0, 1, link);
            
            // create the red rover upload
            redRoverForm.setAction(GWT.getModuleBaseURL() + "RedRoverServlet");
            redRoverForm.setEncoding(FormPanel.ENCODING_MULTIPART);
            redRoverForm.setMethod(FormPanel.METHOD_POST);
            redRoverForm.setWidget(roverTable);
            
            // the file upload lable
            Label uploadLabelRedRover = new Label(constants.settingsCSVUpload()); //TODO: use constant
            roverTable.setWidget(1, 0, uploadLabelRedRover);
            
            // the file upload element
            FileUpload uploadRedRover = new FileUpload();
            uploadRedRover.setName("RedRoverUploadFormElement");
            roverTable.setWidget(1, 1, uploadRedRover);

            // a button to commit the upload
            Button buttonRedRover = new Button( constants.settingsUpload() ); //TODO: use constant
            buttonRedRover.addClickListener(new ClickListener(){
                public void onClick(Widget sender) {
                    redRoverForm.submit();
                }
            });
            roverTable.setWidget(1, 2, buttonRedRover);
            
            redRoverForm.addFormHandler(new FormHandler(){

                Date start = null;
                
                public void onSubmit(FormSubmitEvent event) {
                    start = new Date();
                    GWT.log("submitting redRoverForm at " + start.toString(), null);
                    Message.get().show( constants.settingsImportingData() );
                }

                public void onSubmitComplete(FormSubmitCompleteEvent event) {
                    Date end = new Date();
                    Long diff = end.getTime() - start.getTime();
                    GWT.log("submit complete at " + end.toString(), null);
                    GWT.log("diff=" + diff.toString(), null);
                    GWT.log("refreshing map with updated buildings", null);
                    //InCAST.get().refreshBuildingsOnMap();
                    Message.get().show( constants.settingsCompletedImport() );
                    // InCAST.get().reloadApplication();
                    
                    // Controller.get()
                    // UIController.get().logout(); // workaround until I can solve the race condition
                }
                
            });
            
            initWidget(redRoverForm);
        }        
    }
   
    private class ImportSettings extends Composite {
        
        private FlexTable importTable = new FlexTable();
        private FormPanel csvForm = new FormPanel();
        
        public ImportSettings()
        {
         
            // create the csv form
            csvForm.setAction(GWT.getModuleBaseURL() + "ImportServlet");
            csvForm.setEncoding(FormPanel.ENCODING_MULTIPART);
            csvForm.setMethod(FormPanel.METHOD_POST);
            csvForm.setWidget(importTable);
            
            // the file upload lable
            Label uploadLabel = new Label( constants.settingsCSVUpload() ); //TODO: use constant
            importTable.setWidget(0, 0, uploadLabel);
            
            // the file upload element
            FileUpload upload = new FileUpload();
            upload.setName("CSVUploadFormElement");
            importTable.setWidget(0, 1, upload);

            // a button to commit the upload
            Button button = new Button( constants.settingsUpload() ); //TODO: use constant
            button.addClickListener(new ClickListener(){
                public void onClick(Widget sender) {
                    csvForm.submit();
                }
            });
            importTable.setWidget(0, 2, button);
            
            csvForm.addFormHandler(new FormHandler(){

                Date start = null;
                
                public void onSubmit(FormSubmitEvent event) {
                    start = new Date();
                    GWT.log("submitting csvForm at " + start.toString(), null);
                    Message.get().show( constants.settingsImportingData() );
                }

                public void onSubmitComplete(FormSubmitCompleteEvent event) {
                    Date end = new Date();
                    Long diff = end.getTime() - start.getTime();
                    GWT.log("submit complete at " + end.toString(), null);
                    GWT.log("diff=" + diff.toString(), null);
                    GWT.log("refreshing map with updated buildings", null);
                    //InCAST.get().refreshBuildingsOnMap();
                    Message.get().show( constants.settingsCompletedImport() );
                    // InCAST.get().reloadApplication();
                    //UIController.get().logout(); // workaround until I can solve the race condition
                }
                
            });
                    
            
            initWidget(csvForm);
        }        
    }
    
    public static void actionWrapperHide()
    {
    	Settings.get().setVisible(false);
    }

	public void showSettings() {
		Settings.get().setVisible(true);
        // check the Login user to see if they are admin
        User currentUser = Login.get().getLoginUser();
        userList.getUsers();
        userList.setControls();
	}

	public void showUserEditor() {
		
		userSettings.showUserEditor();
		
	}

	public void showUserList() {
		userSettings.showUserList();
	}
	
	public void addNewUser() {
		userSettings.addNewUser();
	}
	
}








